
#include "gui_misc_widgets.h"

using namespace WtfGui;
using namespace WtfGui::Widgets;
using namespace WtfEngine;


/**** Popup Widget ****/

Popup::Popup(const WtfGui::Widget::tRef &rWidget)
: WidgetContainer("") {
	WidgetContainer::AddChild(rWidget);
	OnChildResize();

	WtfEngine::Kernel::GetInstance().GetGameState()->BindEvent(
		new WtfEngine::MouseDownEvent(), WtfEngine::EventHandler(
			new WtfEngine::ObjFunctor<Popup>(this, &Popup::OnMouseDownStart), EventHandler::PRIO_WM_HIGH));
};

void Popup::OnMouseDownStart() {
	// Mouse has been clicked - close the popup if it doesn't get clicked on
	WtfEngine::IDynamic::Init();
};

bool Popup::OnMouseDown(const iVector2D& vPos, WtfEngine::tMouseButton btn) {
	// We've been clicked on - not closing
	WtfEngine::IDynamic::Destroy();
	return WidgetContainer::OnMouseDown(vPos, btn);
};

void Popup::Update() {
	Remove();
};

void Popup::OnResize() {
	// Don't notify child widgets - unguarded recursion
	Widget::OnResize();
};

void Popup::OnChildResize() {
	setInnerSize((*mChildren.begin())->getSize());
	WidgetContainer::OnChildResize();
};

void Popup::Remove() {
	WtfEngine::IDynamic::Destroy();
	WidgetContainer::Remove();

	WtfEngine::Kernel::GetInstance().RemoveHandler(new WtfEngine::ObjFunctor<Popup>(this, &Popup::OnMouseDownStart));
};


/**** Colour Picker ****/


struct HslColour {
	fVector4D vValue;

	inline HslColour(const fVector4D& v)
	: vValue(v) {
	};

	/// Conversion to RBGA
	inline operator fVector4D() const {
		float v;
		float h = vValue[0], sl = vValue[1], l = vValue[2];
		fVector4D vRgb(1, 1, 1, vValue[3]);
		
		v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
		if (v > 0)
		{
			  float m;
			  float sv;
			  int sextant;
			  float fract, vsf, mid1, mid2;

			  m = l + l - v;
			  sv = (v - m ) / v;
			  h *= 6.0;
			  sextant = (int)h;
			  fract = h - sextant;
			  vsf = v * sv * fract;
			  mid1 = m + vsf;
			  mid2 = v - vsf;
			  switch (sextant) {
					case 0:
						  vRgb[0] = v; vRgb[1] = mid1; vRgb[2] = m;
						  break;
					case 1:
						  vRgb[0] = mid2; vRgb[1] = v; vRgb[2] = m;
						  break;
					case 2:
						  vRgb[0] = m; vRgb[1] = v; vRgb[2] = mid1;
						  break;
					case 3:
						  vRgb[0] = m; vRgb[1] = mid2; vRgb[2] = v;
						  break;
					case 4:
						  vRgb[0] = mid1; vRgb[1] = m; vRgb[2] = v;
						  break;
					case 5:
						  vRgb[0] = v; vRgb[1] = m; vRgb[2] = mid2;
						  break;
			  }
		}
		return vRgb;
	};
};

ColourPicker::ColourPicker()
: Image(WtfEngine::FBOTexture::tRef(new WtfEngine::FBOTexture())), mrPaletteImage(dynamic_cast<WtfEngine::FBOTexture*>(&*getImage())) {
	// Set zero padding
	Resize(iVector2D(100, 250), iVector2D());
};

bool ColourPicker::OnMouseDown(const iVector2D &vPos, WtfEngine::tMouseButton btn) {
	return true;
};

void ColourPicker::OnResize() {
	// Resize palette
	int x = getInnerSize()[0], y = getInnerSize()[1];
	mrPaletteImage->Create(x, y);

	// Draw the palette using OpenGL
	mrPaletteImage->Activate();
	glBegin(GL_QUADS); {
		glColor4fv(((fVector4D)HslColour(fVector4D(1.0, 1.0, 1.0, 1.0))).toArray());
		glVertex2i(0, 0);
		glColor4fv(((fVector4D)HslColour(fVector4D(0, 1.0, 1.0, 1.0))).toArray());
		glVertex2i(0, y);
		glColor4fv(((fVector4D)HslColour(fVector4D(0, 0, 1.0, 1.0))).toArray());
		glVertex2i(x, y);
		glColor4fv(((fVector4D)HslColour(fVector4D(1.0, 0, 1.0, 1.0))).toArray());
		glVertex2i(x, 0);
	}; glEnd();

	mrPaletteImage->Deactivate();
};
